-module( geom ).
-export( [ zeroVec3/0, vec3add/2, vec3sub/2, vec3scale/2, vec3mult/2, vec3dp/2, vec3square/1, vec3len/1, vec3normalize/1, vec3combine/4, vec3combine/6, vec3ma/3, vec3ma/5 ] ).
-export( [ zeroBox/0, boxSize/1, boxCenter/1, boxIn/2 ] ).

zeroVec3() -> { 0.0, 0.0, 0.0 }.

vec3add( {X0, Y0, Z0}, {X1, Y1, Z1} ) ->
  { X0 + X1, Y0 + Y1, Z0 + Z1 }.

vec3sub( {X0, Y0, Z0}, {X1, Y1, Z1} ) ->
  { X0 - X1, Y0 - Y1, Z0 - Z1 }.
  
vec3scale( {X, Y, Z}, K ) when is_number( K ) ->
  { X * K, Y * K, Z * K }.

vec3mult( {X0, Y0, Z0}, {X1, Y1, Z1} ) ->
  { X0 * X1, Y0 * Y1, Z0 * Z1 }.

vec3dp( {X0, Y0, Z0}, {X1, Y1, Z1} ) ->
  { X0 * X1 + Y0 * Y1 + Z0 * Z1 }.
  
vec3square( {X, Y, Z} ) ->
  { X * X + Y * Y + Z * Z }.
  
vec3len( {X, Y, Z} ) ->
  math:sqrt( X * X + Y * Y + Z * Z ).
  
vec3normalize( V = {X, Y, Z} ) ->
  L = vec3len( V ),
  { X / L, Y / L, Z / L }.
  
vec3combine( {X0, Y0, Z0}, {X1, Y1, Z1}, K0, K1 ) when is_number( K0 ), is_number( K1 ) ->
  {
    X0 * K0 + X1 * K1,
    Y0 * K0 + Y1 * K1,
    Z0 * K0 + Z1 * K1
  }.
  
vec3combine( {X0, Y0, Z0}, {X1, Y1, Z1}, {X2, Y2, Z2}, K0, K1, K2 ) when is_number( K0 ), is_number( K1 ), is_number( K2 ) ->
  {
    X0 * K0 + X1 * K1 + X2 * K2,
    Y0 * K0 + Y1 * K1 + Y2 * K2,
    Z0 * K0 + Z1 * K1 + Z2 * K2
  }.

vec3ma( {X0, Y0, Z0}, {X1, Y1, Z1}, K1 ) when is_number( K1 ) ->
  {
    X0 + X1 * K1,
    Y0 + Y1 * K1,
    Z0 + Z1 * K1
  }.

vec3ma( {X0, Y0, Z0}, {X1, Y1, Z1}, {X2, Y2, Z2}, K1, K2 ) when is_number( K1 ), is_number( K2 ) ->
  {
    X0 + X1 * K1 + X2 * K2,
    Y0 + Y1 * K1 + Y2 * K2,
    Z0 + Z1 * K1 + Z2 * K2
  }.


zeroBox() -> { zeroVec3(), zeroVec3() }.
  
boxSize( { Min, Max } ) ->
  vec3sub( Max, Min ).

boxCenter( { Min, Max } ) ->
  vec3combine( Min, Max, 0.5, 0.5 ).

boxIn( { {MinX, MinY, MinZ}, {MaxX, MaxY, MaxZ} }, {X, Y, Z} ) ->
  ( X >= MinX ) andalso ( X =< MaxX ) andalso
  ( Y >= MinY ) andalso ( Y =< MaxY ) andalso
  ( Z >= MinZ ) andalso ( Z =< MaxZ ).
